package cn.hsw.platform.service.impl;

import cn.hsw.platform.contants.ManageConstant;
import cn.hsw.platform.core.doc.dto.AuthUserDto;
import cn.hsw.platform.core.doc.util.AuthUtil;
import cn.hsw.platform.core.base.BaseServiceImpl;
import cn.hsw.platform.core.util.BeanUtil;
import cn.hsw.platform.core.util.Validator;
import cn.hsw.platform.dto.HomeInfo;
import cn.hsw.platform.dto.LogoInfo;
import cn.hsw.platform.dto.MenuDto;
import cn.hsw.platform.dto.MenuInfo;
import cn.hsw.platform.model.PermissionModel;
import cn.hsw.platform.model.RolePermissionCenter;
import cn.hsw.platform.repository.PermissionRepository;
import cn.hsw.platform.repository.RolePermissionCenterRepository;
import cn.hsw.platform.service.PermissionService;
import cn.hsw.platform.vo.PermissionVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 权限服务
 * @author 李子木
 * @date 2020-11-04
 */
@Service
public class PermissionServiceImpl extends BaseServiceImpl<PermissionRepository,PermissionModel,Long> implements PermissionService {


    @Autowired
    RolePermissionCenterRepository rolePermissionCenterRepository;

    @Autowired
    AuthUtil authUtil;

    @Override
    public PermissionModel findByCode(String code) {

        return getRepository().findByCode(code);
    }

    @Override
    public List<PermissionModel> findByParentPidNull() {
        return getRepository().findByParentPidNull(Sort.by(Sort.Direction.ASC,"sort","createTime"));
    }

    @Override
    public void edit(PermissionModel permissionModel, PermissionVO permissionVO) {

        List<Long> subPidS = subPidS(permissionModel.getPermissionModelList(), new ArrayList<>());
        subPidS.add(permissionModel.getPid());

        Validator.validateContains(subPidS,permissionVO.getParentPid(),"不能选自己或自己的子节点作为父节点");

        if(Validator.isNotNull(permissionVO.getName())){
            permissionModel.setName(permissionVO.getName());
        }

        if(Validator.isNotNull(permissionVO.getUrl())){
            permissionModel.setUrl(permissionVO.getUrl());
        }

        if(Validator.isNotNull(permissionVO.getState())){
            Validator.validateContains(new String[]{ManageConstant.PERMISSION_STATE_SHOW+"",ManageConstant.PERMISSION_STATE_NOT_SHOW+""}
                    ,permissionVO.getState()+"","状态必须是"+ManageConstant.PERMISSION_STATE_SHOW+ManageConstant.PERMISSION_STATE_NOT_SHOW);
            permissionModel.setState(permissionVO.getState());
        }

        if(Validator.isNotNull(permissionVO.getCode())){

            PermissionModel codePermissionModel = getRepository().findByCode(permissionVO.getCode());
            if(Validator.isNotNull(codePermissionModel)){
                //不为空的情况下 只能和自己用的一个才可以继续用
                Validator.validateEqual(codePermissionModel.getPid(),permissionModel.getPid(),"权限code已经存在");
            }
            permissionModel.setCode(permissionVO.getCode());
        }

        if(Validator.isNotNull(permissionVO.getSort())){
            permissionModel.setSort(permissionVO.getSort());
        }
        if(Validator.isNotNull(permissionVO.getRemark())){
            permissionModel.setRemark(permissionVO.getRemark());
        }

        this.save(permissionModel);
        authUtil.clearPermissionPidCache();
    }

    @Override
    public MenuDto menu(Long userPid) {
        /*通过用户ID获取角色列表*/
        AuthUserDto authUserDto = authUtil.getAuthUserDto(userPid);

        /*通过角色ID获取所有的菜单*/
        List<RolePermissionCenter> rolePermissionCenterList = rolePermissionCenterRepository.findByRolePidIn(authUserDto.getRolePidList());

        List<Long> permissionPidList = rolePermissionCenterList.stream().map(RolePermissionCenter::getPermissionPid).collect(Collectors.toList());

        List<PermissionModel> permissionModelList = getRepository().findByTypeNotAndStateAndPidIn(ManageConstant.PERMISSION_TYPE_API, ManageConstant.PERMISSION_STATE_SHOW, permissionPidList);

        /*转换bean*/
        List<MenuInfo> list = BeanUtil.copyListProperties(permissionModelList, MenuInfo::new, (permissionModel, menuInfo) -> {
            menuInfo.setHref(permissionModel.getUrl());
            menuInfo.setIcon(permissionModel.getIcon());
            menuInfo.setTarget(permissionModel.getTarget());
            menuInfo.setTitle(permissionModel.getName());
            menuInfo.setPid(permissionModel.getPid());
            menuInfo.setParentPid(permissionModel.getParentPid());
        });

        /*分组*/
        Map<Long, List<MenuInfo>> nodeByParentIdMap = list.stream().collect(Collectors.groupingBy(menuInfo -> {
            if(Validator.isEmpty(menuInfo.getParentPid())){
                return 0L;
            }else{
                return menuInfo.getParentPid();
            }
        }));
        /*循环遍历*/
        list.forEach(menuInfo -> menuInfo.setChild(nodeByParentIdMap.get(menuInfo.getPid())));
        /*过滤*/
        List<MenuInfo> menuInfoList = list.stream().filter(menuInfo -> Validator.isNull(menuInfo.getParentPid())).collect(Collectors.toList());

        MenuDto menuDto = new MenuDto();    
        menuDto.setMenuInfo(menuInfoList);
        HomeInfo homeInfo = new HomeInfo();
        homeInfo.setHref("page/welcome.html?t=1");
        homeInfo.setTitle("首页");
        menuDto.setHomeInfo(homeInfo);
        LogoInfo logoInfo = new LogoInfo();
        logoInfo.setHref("");
        logoInfo.setImage("images/logo.png");
        logoInfo.setTitle("Hsw");
        menuDto.setLogoInfo(logoInfo);
        return menuDto;
    }

    private List<Long> subPidS(List<PermissionModel> list,List<Long> subPidS){
        list.forEach(permissionModel -> {
            subPidS.add(permissionModel.getPid());
            if(permissionModel.getPermissionModelList().size()>0){
                subPidS(permissionModel.getPermissionModelList(),subPidS);
            }

        });
       return subPidS;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(PermissionModel entity) {
        super.delete(entity);
        rolePermissionCenterRepository.deleteByPermissionPid(entity.getPid());
        authUtil.clearPermissionPidCache();
    }
}
